import pandas as pd
import plotly.express as px
from dash import Dash, dcc, html, Input, Output, State
from src.core.stu_grade_pre.stu_grade_pre import analyze_student


def create_prediction_layout():
    return html.Div(
        style={
            'fontFamily': 'Arial, sans-serif',
            'maxWidth': '1200px',
            'margin': '0 auto',
            'padding': '20px',
            'backgroundColor': '#f5f6fa'
        },
        children=[
            html.H1(
                '📈 学业成绩预测',
                style={
                    'color': '#2c3e50',
                    'textAlign': 'center',
                    'marginBottom': '40px',
                    'textShadow': '2px 2px 4px rgba(0,0,0,0.1)'
                }
            ),
            html.Div(
                style={
                    'display': 'flex',
                    'gap': '15px',
                    'marginBottom': '40px',
                    'justifyContent': 'center'
                },
                children=[
                    dcc.Input(
                        id='stu-id-input',
                        type='text',
                        placeholder='请输入学生ID...',
                        style={
                            'width': '350px',
                            'padding': '12px 20px',
                            'border': '2px solid #3498db',
                            'borderRadius': '8px',
                            'fontSize': '16px'
                        }
                    ),
                    html.Button(
                        '立即分析',
                        id='predict-btn',
                        style={
                            'padding': '12px 30px',
                            'backgroundColor': '#3498db',
                            'color': 'white',
                            'border': 'none',
                            'borderRadius': '8px',
                            'cursor': 'pointer',
                            'fontSize': '16px',
                            'transition': 'all 0.3s',
                            ':hover': {
                                'backgroundColor': '#2980b9'
                            }
                        }
                    )
                ]
            ),
            dcc.Loading(
                id="prediction-loading",
                type="cube",
                color="#3498db",
                children=[
                    html.Div(id='prediction-result', style={'marginTop': '20px'})
                ]
            )
        ]
    )


def create_subject_card(subject, data):
    trend_colors = {
        "上升趋势": "#2ecc71",
        "下降趋势": "#e74c3c",
        "波动趋势": "#f1c40f",
        "数据不足": "#95a5a6"
    }

    return html.Div(
        style={
            'backgroundColor': 'white',
            'padding': '20px',
            'borderRadius': '12px',
            'boxShadow': '0 4px 6px rgba(0,0,0,0.1)',
            'marginBottom': '20px'
        },
        children=[
            html.Div(
                style={
                    'display': 'flex',
                    'justifyContent': 'space-between',
                    'marginBottom': '15px'
                },
                children=[
                    html.H3(
                        subject,
                        style={
                            'color': '#2c3e50',
                            'margin': '0',
                            'fontSize': '20px'
                        }
                    ),
                    html.Div(
                        f"趋势：{data['成绩趋势']}",
                        style={
                            'color': trend_colors.get(data['成绩趋势'], '#95a5a6'),
                            'fontWeight': 'bold'
                        }
                    )
                ]
            ),
            html.Div(
                style={
                    'display': 'grid',
                    'gridTemplateColumns': '1fr 1fr 1fr',
                    'gap': '20px'
                },
                children=[
                    html.Div(
                        style={'textAlign': 'center'},
                        children=[
                            html.Div(
                                "预测成绩",
                                style={
                                    'color': '#7f8c8d',
                                    'fontSize': '14px',
                                    'marginBottom': '5px'
                                }
                            ),
                            html.Div(
                                f"{data['预测成绩']}",
                                style={
                                    'color': '#3498db',
                                    'fontSize': '24px',
                                    'fontWeight': 'bold'
                                }
                            )
                        ]
                    ),
                    html.Div(
                        style={'textAlign': 'center'},
                        children=[
                            html.Div(
                                "历史平均",
                                style={
                                    'color': '#7f8c8d',
                                    'fontSize': '14px',
                                    'marginBottom': '5px'
                                }
                            ),
                            html.Div(
                                f"{data['平均分']:.1f}",
                                style={
                                    'color': '#e67e22',
                                    'fontSize': '24px',
                                    'fontWeight': 'bold'
                                }
                            )
                        ]
                    ),
                    html.Div(
                        style={'textAlign': 'center'},
                        children=[
                            html.Div(
                                "考试次数",
                                style={
                                    'color': '#7f8c8d',
                                    'fontSize': '14px',
                                    'marginBottom': '5px'
                                }
                            ),
                            html.Div(
                                f"{len(data['历史成绩'])}次",
                                style={
                                    'color': '#27ae60',
                                    'fontSize': '24px',
                                    'fontWeight': 'bold'
                                }
                            )
                        ]
                    )
                ]
            ),
            dcc.Graph(
                figure=px.line(
                    pd.DataFrame(data['历史成绩']),
                    x='时间',
                    y='成绩',
                    title=f'{subject}成绩趋势',
                    markers=True
                ).update_layout(
                    plot_bgcolor='rgba(0,0,0,0)',
                    paper_bgcolor='rgba(0,0,0,0)',
                    xaxis_title=None,
                    yaxis_title='成绩',
                    height=300
                )
            )
        ]
    )


def register_callbacks(app):
    @app.callback(
        Output('prediction-result', 'children'),
        Input('predict-btn', 'n_clicks'),
        State('stu-id-input', 'value')
    )
    def update_prediction(n_clicks, stu_id):
        if not stu_id:
            return html.Div(
                '⚠️ 请输入有效的学生ID',
                style={
                    'color': '#e74c3c',
                    'textAlign': 'center',
                    'padding': '20px',
                    'fontSize': '18px'
                }
            )

        try:
            student_result = analyze_student(stu_id, alpha=0.4)

            if 'error' in student_result:
                return html.Div(
                    f"⚠️ {student_result['error']}",
                    style={
                        'color': '#e74c3c',
                        'textAlign': 'center',
                        'padding': '20px',
                        'fontSize': '18px'
                    }
                )

            # 提取学科数据（排除总分）
            subjects = sorted([sub for sub in student_result.keys() if sub != '总分'])

            # 创建总分分析卡片
            total_score_data = student_result.get('总分', {})
            pie_data = [{'学科': sub, '预测成绩': student_result[sub]['预测成绩']} for sub in subjects]
            df_pie = pd.DataFrame(pie_data)

            pie_fig = px.pie(
                df_pie,
                names='学科',
                values='预测成绩',
                title='各科预测成绩分布',
                color_discrete_sequence=px.colors.qualitative.Pastel,
                hole=0.3
            ).update_layout(
                plot_bgcolor='rgba(0,0,0,0)',
                paper_bgcolor='rgba(0,0,0,0)',
                height=400,
                title_x=0.5,
                showlegend=True
            )

            total_score_card = html.Div(
                style={
                    'backgroundColor': 'white',
                    'padding': '20px',
                    'borderRadius': '12px',
                    'boxShadow': '0 4px 6px rgba(0,0,0,0.1)',
                    'marginBottom': '20px'
                },
                children=[
                    html.H3(
                        "总分预测分析",
                        style={
                            'color': '#2c3e50',
                            'textAlign': 'center',
                            'marginBottom': '20px',
                            'fontSize': '20px'
                        }
                    ),
                    html.Div(
                        style={
                            'display': 'grid',
                            'gridTemplateColumns': 'repeat(3, 1fr)',
                            'gap': '20px',
                            'marginBottom': '20px'
                        },
                        children=[
                            html.Div(
                                style={'textAlign': 'center'},
                                children=[
                                    html.Div("预测总分",
                                             style={'color': '#7f8c8d', 'fontSize': '14px'}),
                                    html.Div(f"{total_score_data.get('预测总分', 0):.1f}",
                                             style={'color': '#3498db', 'fontSize': '24px', 'fontWeight': 'bold'})
                                ]
                            ),
                            html.Div(
                                style={'textAlign': 'center'},
                                children=[
                                    html.Div("平均分",
                                             style={'color': '#7f8c8d', 'fontSize': '14px'}),
                                    html.Div(f"{total_score_data.get('平均总分', 0):.1f}",
                                             style={'color': '#e67e22', 'fontSize': '24px', 'fontWeight': 'bold'})
                                ]
                            ),
                            html.Div(
                                style={'textAlign': 'center'},
                                children=[
                                    html.Div("参与科目数",
                                             style={'color': '#7f8c8d', 'fontSize': '14px'}),
                                    html.Div(f"{total_score_data.get('参与科目数', 0)}",
                                             style={'color': '#27ae60', 'fontSize': '24px', 'fontWeight': 'bold'})
                                ]
                            )
                        ]
                    ),
                    dcc.Graph(figure=pie_fig)
                ]
            )

            # 生成学科卡片
            subject_cards = [create_subject_card(sub, student_result[sub]) for sub in subjects]

            return html.Div([
                total_score_card,
                html.Div(
                    style={
                        'display': 'grid',
                        'gridTemplateColumns': 'repeat(auto-fit, minmax(400px, 1fr))',
                        'gap': '20px',
                        'marginBottom': '30px'
                    },
                    children=subject_cards
                )
            ])

        except Exception as e:
            return html.Div(
                f'⚠️ 发生错误: {str(e)}',
                style={
                    'color': '#e74c3c',
                    'textAlign': 'center',
                    'padding': '20px',
                    'fontSize': '18px'
                }
            )


def init_prediction_app(server):
    app = Dash(
        __name__,
        server=server,
        url_base_pathname='/grade_predictions/',
        suppress_callback_exceptions=True
    )
    app.layout = create_prediction_layout()
    register_callbacks(app)
    return app